package com.lyandwc.lw_bbs.controller;

import com.alibaba.fastjson.JSONObject;
import com.lyandwc.lw_bbs.entity.Category;
import com.lyandwc.lw_bbs.entity.Comment;
import com.lyandwc.lw_bbs.entity.Topic;
import com.lyandwc.lw_bbs.service.*;
import com.lyandwc.lw_bbs.utils.ResponseUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/comments")
public class CommentController {
    private CategoryService categoryService;
    private TopicService topicService;
    private CommentService commentService;
    private NotificationService notificationService;
    private UserService userService;

    public CommentController(CategoryService categoryService, TopicService topicService, CommentService commentService, NotificationService notificationService, UserService userService) {
        this.categoryService = categoryService;
        this.topicService = topicService;
        this.commentService = commentService;
        this.notificationService = notificationService;
        this.userService = userService;
    }

    @RequestMapping(method = RequestMethod.GET)
    public JSONObject getComments(
            @RequestParam int topicId,
            @RequestParam int page,
            @RequestParam int limit
    ) {
        if (topicId < 1 || page < 1 || limit < 1) {
            return ResponseUtils.fail("Illegal format params.");
        }

        return ResponseUtils.success(commentService.listCommentsByTopicId(topicId, page, limit));
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public JSONObject getComment(
            @PathVariable int id
    ) {
        return ResponseUtils.success(commentService.findCommentById(id));
    }

    @PreAuthorize(value = "hasAnyRole('ADMIN', 'USER')")
    @RequestMapping(value = "/{id}", method = RequestMethod.POST)
    public JSONObject replyComment(
            Authentication authentication,
            @PathVariable int id,
            @RequestBody Map<String, String> map
    ) {
        String content = map.get("content");
        int userId = (int) authentication.getCredentials();
        Comment comment = commentService.insertReplyComment(content, id, userId);
        Comment replyComment = commentService.getById(id);

        Topic topic = topicService.updateCount(comment.getTopicId());
        categoryService.updateCount(topic.getCategoryId());
        notificationService.addNotification(0, replyComment.getId(), replyComment.getUserId(), comment.getId(), comment.getUserId());
        userService.updateCount(userId);

        return ResponseUtils.success(comment);
    }

    @PreAuthorize(value = "hasAnyRole('ADMIN', 'USER')")
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public JSONObject deleteComment(
            Authentication authentication,
            @PathVariable int id
    ) {
        int userId = (int) authentication.getCredentials();
        Comment comment = commentService.getById(id);

        if (comment.getUserId() != userId) {
            return ResponseUtils.fail("Unauthorized operation.");
        }

        commentService.removeById(comment.getId());

        Topic topic = topicService.updateCount(comment.getTopicId());
        Category category = categoryService.updateCount(topic.getCategoryId());
        userService.updateCount(userId);

        return ResponseUtils.success(comment);
    }

    @PreAuthorize(value = "hasAnyRole('ADMIN', 'USER')")
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public JSONObject updateComment(
            Authentication authentication,
            @PathVariable int id,
            @RequestBody Map<String, String> map
    ) {
        int userId = (int) authentication.getCredentials();
        String content = map.get("content");
        Comment comment = commentService.getById(id);

        if (comment.getUserId() != userId) {
            return ResponseUtils.fail("Unauthorized operation.");
        }

        return ResponseUtils.success(commentService.updateComment(id, content));
    }

    @PreAuthorize(value = "hasAnyRole('ADMIN', 'USER')")
    @RequestMapping(value = "/{id}/like", method = RequestMethod.GET)
    public JSONObject likeComment(
            Authentication authentication,
            @PathVariable int id
    ) {
        Comment comment = commentService.likeComment(id);

        Topic topic = topicService.updateCount(comment.getTopicId());
        Category category = categoryService.updateCount(topic.getCategoryId());
        notificationService.addNotification(1, comment.getId(), comment.getUserId(), -1, (int) authentication.getCredentials());

        return ResponseUtils.success(comment);
    }

    @PreAuthorize(value = "hasAnyRole('ADMIN', 'USER')")
    @RequestMapping(value = "/{id}/dislike", method = RequestMethod.GET)
    public JSONObject dislikeComment(
            Authentication authentication,
            @PathVariable int id
    ) {
        Comment comment = commentService.dislikeComment(id);

        Topic topic = topicService.updateCount(comment.getTopicId());
        Category category = categoryService.updateCount(topic.getCategoryId());
        notificationService.addNotification(2, comment.getId(), comment.getUserId(), -1, (int) authentication.getCredentials());

        return ResponseUtils.success(comment);
    }
}
